﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Windows.Forms;
using System.IO;
using System.Diagnostics;

using AxMSTSCLib;

namespace PTN.SSMS.AddIns.V2.NetworkTools.UI.Controls
{
	public partial class RDPControl : UserControl
	{
	#region Members
		private AxMsRdpClient5 rdpClient5 = null;
		private AxMsRdpClient6 rdpClient6 = null;
		private Boolean isRDPClient6Supported = false;
		private Version rdpVersion = null;
	#endregion

	#region Properties
		public Version RDPVersion
		{
			get { return this.rdpVersion; }
		}
		private AxMsRdpClient5 RdpClient5
		{
			get { return this.rdpClient5; }
		}
		private AxMsRdpClient6 RdpClient6
		{
			get { return this.rdpClient6; }
		}
		private Boolean IsRDPClient6Supported
		{
			get { return this.isRDPClient6Supported; }
		}

		public int ColorDepth
		{
			get { return this.IsRDPClient6Supported ? this.RdpClient6.ColorDepth : this.RdpClient5.ColorDepth; } 
			set
			{
				if (this.IsRDPClient6Supported)
					this.RdpClient6.ColorDepth = value;
				else
					this.RdpClient5.ColorDepth = value;
			} 
		}
		public short Connected
		{
			get { return this.IsRDPClient6Supported ? this.RdpClient6.Connected : this.RdpClient5.Connected; }
		}
		public string ConnectedStatusText
		{
			get { return this.IsRDPClient6Supported ? this.RdpClient6.ConnectedStatusText : this.RdpClient5.ConnectedStatusText; } 
			set
			{
				if (this.IsRDPClient6Supported)
					this.RdpClient6.ConnectedStatusText = value;
				else
					this.RdpClient5.ConnectedStatusText = value;
			} 
		}
		public string ConnectingText
		{
			get { return this.IsRDPClient6Supported ? this.RdpClient6.ConnectingText : this.RdpClient5.ConnectingText; } 
			set
			{
				if (this.IsRDPClient6Supported)
					this.RdpClient6.ConnectingText = value;
				else
					this.RdpClient5.ConnectingText = value;
			} 
		}
		public int DesktopHeight
		{
			get { return this.IsRDPClient6Supported ? this.RdpClient6.DesktopHeight : this.RdpClient5.DesktopHeight; } 
			set
			{
				if (this.IsRDPClient6Supported)
					this.RdpClient6.DesktopHeight = value;
				else
					this.RdpClient5.DesktopHeight = value;
			} 
		}
		public int DesktopWidth
		{
			get { return this.IsRDPClient6Supported ? this.RdpClient6.DesktopWidth : this.RdpClient5.DesktopWidth; } 
			set
			{
				if (this.IsRDPClient6Supported)
					this.RdpClient6.DesktopWidth = value;
				else
					this.RdpClient5.DesktopWidth = value;
			} 
		}
		public string DisconnectedText
		{
			get { return this.IsRDPClient6Supported ? this.RdpClient6.DisconnectedText : this.RdpClient5.DisconnectedText; } 
			set
			{
				if (this.IsRDPClient6Supported)
					this.RdpClient6.DisconnectedText = value;
				else
					this.RdpClient5.DisconnectedText = value;
			} 
		}
		public string Domain
		{
			get { return this.IsRDPClient6Supported ? this.RdpClient6.Domain : this.RdpClient5.Domain; } 
			set
			{
				if (this.IsRDPClient6Supported)
					this.RdpClient6.Domain = value;
				else
					this.RdpClient5.Domain = value;
			} 
		}
		public string Server
		{
			get { return this.IsRDPClient6Supported ? this.RdpClient6.Server : this.RdpClient5.Server; } 
			set
			{
				if (this.IsRDPClient6Supported)
					this.RdpClient6.Server = value;
				else
					this.RdpClient5.Server = value;
			} 
		}
		public string UserName 
		{
			get { return this.IsRDPClient6Supported ? this.RdpClient6.UserName  : this.RdpClient5.UserName ; } 
			set
			{
				if (this.IsRDPClient6Supported)
					this.RdpClient6.UserName  = value;
				else
					this.RdpClient5.UserName  = value;
			} 
		}
		public string Version
		{
			get { return this.IsRDPClient6Supported ? this.RdpClient6.Version : this.RdpClient5.Version; } 
		}

		public bool EnableAutoReconnect 
		{ 
			get { return this.IsRDPClient6Supported ? this.RdpClient6.AdvancedSettings7.EnableAutoReconnect : this.RdpClient5.AdvancedSettings6.EnableAutoReconnect; } 
			set
			{
				if (this.IsRDPClient6Supported)
					this.RdpClient6.AdvancedSettings7.EnableAutoReconnect = value;
				else 
					this.RdpClient5.AdvancedSettings6.EnableAutoReconnect = value;
			} 
		}
		public int MaxReconnectAttempts 
		{ 
			get { return this.IsRDPClient6Supported ? this.RdpClient6.AdvancedSettings7.MaxReconnectAttempts : this.RdpClient5.AdvancedSettings6.MaxReconnectAttempts; }
			set
			{
				if (this.IsRDPClient6Supported)
					this.RdpClient6.AdvancedSettings7.MaxReconnectAttempts = value;
				else 
					this.RdpClient5.AdvancedSettings6.MaxReconnectAttempts = value;
			} 
		}
		public bool GrabFocusOnConnect 
		{ 
			get { return this.IsRDPClient6Supported ? this.RdpClient6.AdvancedSettings7.GrabFocusOnConnect : this.RdpClient5.AdvancedSettings6.GrabFocusOnConnect; }
			set
			{
				if (this.IsRDPClient6Supported)
					this.RdpClient6.AdvancedSettings7.GrabFocusOnConnect = value;
				else 
					this.RdpClient5.AdvancedSettings6.GrabFocusOnConnect = value;
			} 
		}
		public bool DisplayConnectionBar
		{ 
			get { return this.IsRDPClient6Supported ? this.RdpClient6.AdvancedSettings7.DisplayConnectionBar : this.RdpClient5.AdvancedSettings6.DisplayConnectionBar; } 
			set
			{
				if (this.IsRDPClient6Supported)
					this.RdpClient6.AdvancedSettings7.DisplayConnectionBar = value;
				else 
					this.RdpClient5.AdvancedSettings6.DisplayConnectionBar = value;
			} 
		}
		public int overallConnectionTimeout
		{ 
			get { return this.IsRDPClient6Supported ? this.RdpClient6.AdvancedSettings7.overallConnectionTimeout : this.RdpClient5.AdvancedSettings6.overallConnectionTimeout; } 
			set
			{
				if (this.IsRDPClient6Supported)
					this.RdpClient6.AdvancedSettings7.overallConnectionTimeout = value;
				else 
					this.RdpClient5.AdvancedSettings6.overallConnectionTimeout = value;
			} 
		}
		public uint AuthenticationLevel
		{ 
			get { return this.IsRDPClient6Supported ? this.RdpClient6.AdvancedSettings7.AuthenticationLevel : this.RdpClient5.AdvancedSettings6.AuthenticationLevel; }
			set
			{
				if (this.IsRDPClient6Supported)
					this.RdpClient6.AdvancedSettings7.AuthenticationLevel = value;
				else 
					this.RdpClient5.AdvancedSettings6.AuthenticationLevel = value;
			} 
		}
		public int RDPPort
		{ 
			get { return this.IsRDPClient6Supported ? this.RdpClient6.AdvancedSettings7.RDPPort : this.RdpClient5.AdvancedSettings6.RDPPort; }
			set
			{
				if (this.IsRDPClient6Supported)
					this.RdpClient6.AdvancedSettings7.RDPPort = value;
				else 
					this.RdpClient5.AdvancedSettings6.RDPPort = value;
			} 
		}
		public string ClearTextPassword
		{ 
			set
			{
				if (this.IsRDPClient6Supported)
					this.RdpClient6.AdvancedSettings7.ClearTextPassword = value;
				else 
					this.RdpClient5.AdvancedSettings6.ClearTextPassword = value;
			} 
		}
		public uint AudioRedirectionMode
		{ 
			get { return this.IsRDPClient6Supported ? this.RdpClient6.AdvancedSettings7.AudioRedirectionMode : this.RdpClient5.AdvancedSettings6.AudioRedirectionMode; }
			set
			{
				if (this.IsRDPClient6Supported)
					this.RdpClient6.AdvancedSettings7.AudioRedirectionMode = value;
				else 
					this.RdpClient5.AdvancedSettings6.AudioRedirectionMode = value;
			} 
		}
		public bool RedirectDrives
		{ 
			get { return this.IsRDPClient6Supported ? this.RdpClient6.AdvancedSettings7.RedirectDrives : this.RdpClient5.AdvancedSettings6.RedirectDrives; }
			set
			{
				if (this.IsRDPClient6Supported)
					this.RdpClient6.AdvancedSettings7.RedirectDrives = value;
				else 
					this.RdpClient5.AdvancedSettings6.RedirectDrives = value;
			} 
		}
		public bool RedirectClipboard
		{ 
			get { return this.IsRDPClient6Supported ? this.RdpClient6.AdvancedSettings7.RedirectClipboard : this.RdpClient5.AdvancedSettings6.RedirectClipboard; } 
			set
			{
				if (this.IsRDPClient6Supported)
					this.RdpClient6.AdvancedSettings7.RedirectClipboard = value;
				else 
					this.RdpClient5.AdvancedSettings6.RedirectClipboard = value;
			} 
		}
		public bool RedirectDevices
		{ 
			get { return this.IsRDPClient6Supported ? this.RdpClient6.AdvancedSettings7.RedirectDevices : this.RdpClient5.AdvancedSettings6.RedirectDevices; }
			set
			{
				if (this.IsRDPClient6Supported)
					this.RdpClient6.AdvancedSettings7.RedirectDevices = value;
				else 
					this.RdpClient5.AdvancedSettings6.RedirectDevices = value;
			} 
		}
		public bool RedirectPorts
		{ 
			get { return this.IsRDPClient6Supported ? this.RdpClient6.AdvancedSettings7.RedirectPorts : this.RdpClient5.AdvancedSettings6.RedirectPorts; } 
			set
			{
				if (this.IsRDPClient6Supported)
					this.RdpClient6.AdvancedSettings7.RedirectPorts = value;
				else 
					this.RdpClient5.AdvancedSettings6.RedirectPorts = value;
			} 
		}
		public bool RedirectPOSDevices
		{ 
			get { return this.IsRDPClient6Supported ? this.RdpClient6.AdvancedSettings7.RedirectPOSDevices : this.RdpClient5.AdvancedSettings6.RedirectPOSDevices; } 
			set
			{
				if (this.IsRDPClient6Supported)
					this.RdpClient6.AdvancedSettings7.RedirectPOSDevices = value;
				else 
					this.RdpClient5.AdvancedSettings6.RedirectPOSDevices = value;
			} 
		}
		public bool RedirectPrinters
		{ 
			get { return this.IsRDPClient6Supported ? this.RdpClient6.AdvancedSettings7.RedirectPrinters : this.RdpClient5.AdvancedSettings6.RedirectPrinters; }
			set
			{
				if (this.IsRDPClient6Supported)
					this.RdpClient6.AdvancedSettings7.RedirectPrinters = value;
				else 
					this.RdpClient5.AdvancedSettings6.RedirectPrinters = value;
			} 
		}
		public bool RedirectSmartCards
		{ 
			get { return this.IsRDPClient6Supported ? this.RdpClient6.AdvancedSettings7.RedirectSmartCards : this.RdpClient5.AdvancedSettings6.RedirectSmartCards; } 
			set
			{
				if (this.IsRDPClient6Supported)
					this.RdpClient6.AdvancedSettings7.RedirectSmartCards = value;
				else 
					this.RdpClient5.AdvancedSettings6.RedirectSmartCards = value;
			} 
		}
		public int PerformanceFlags
		{ 
			get { return this.IsRDPClient6Supported ? this.RdpClient6.AdvancedSettings7.PerformanceFlags : this.RdpClient5.AdvancedSettings6.PerformanceFlags; } 
			set
			{
				if (this.IsRDPClient6Supported)
					this.RdpClient6.AdvancedSettings7.PerformanceFlags = value;
				else 
					this.RdpClient5.AdvancedSettings6.PerformanceFlags = value;
			} 
		}
		public bool ConnectToServerConsole
		{
			get { return this.IsRDPClient6Supported ? this.RdpClient6.AdvancedSettings7.ConnectToAdministerServer : this.RdpClient5.AdvancedSettings6.ConnectToServerConsole; } 
			set
			{
				if (this.IsRDPClient6Supported)
				{
					this.RdpClient6.AdvancedSettings7.ConnectToAdministerServer = value;
				}
				else
					this.RdpClient5.AdvancedSettings6.ConnectToServerConsole = value;
			} 
		}
		public bool SmartSizing
		{
			get { return this.IsRDPClient6Supported ? this.RdpClient6.AdvancedSettings7.SmartSizing : this.RdpClient5.AdvancedSettings6.SmartSizing; }
			set
			{
				if (this.IsRDPClient6Supported)
				{
					this.RdpClient6.AdvancedSettings7.SmartSizing = value;
				}
				else
					this.RdpClient5.AdvancedSettings6.SmartSizing = value;
			}
		}


	#endregion

	#region Events
		public event IMsTscAxEvents_OnConfirmCloseEventHandler OnConfirmClose;
		public event IMsTscAxEvents_OnLogonErrorEventHandler OnLogonError;
		public event IMsTscAxEvents_OnWarningEventHandler OnWarning;
		public event EventHandler OnConnected;
		public event EventHandler OnConnecting;
		public event EventHandler OnLoginComplete;
		public event IMsTscAxEvents_OnDisconnectedEventHandler OnDisconnected;
		public event IMsTscAxEvents_OnFatalErrorEventHandler OnFatalError;
		public event EventHandler OnRDPResize;
	#endregion

	#region Constructors
		public RDPControl()
		{
			InitializeComponent();

			System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(RDPControl));

			this.rdpVersion = GetRDPVersion();
			if (this.RDPVersion != null)
			{
				if (this.RDPVersion >= (new Version(6,0,6001,18000)))
				{
					this.rdpClient6 = new AxMsRdpClient6();

					((System.ComponentModel.ISupportInitialize) (this.RdpClient6)).BeginInit();

					this.RdpClient6.Dock = System.Windows.Forms.DockStyle.Fill;
					this.RdpClient6.Enabled = true;
					this.RdpClient6.Location = new System.Drawing.Point(0,25);
					this.RdpClient6.Name = "rdpClient";
					this.RdpClient6.OcxState = ((System.Windows.Forms.AxHost.State) (resources.GetObject("rdpClient.OcxState")));
					this.RdpClient6.Size = new System.Drawing.Size(800,575);
					this.RdpClient6.TabIndex = 1;
					this.RdpClient6.OnConfirmClose += new AxMSTSCLib.IMsTscAxEvents_OnConfirmCloseEventHandler(this.OnRdpClientConfirmClose);
					this.RdpClient6.OnLogonError += new AxMSTSCLib.IMsTscAxEvents_OnLogonErrorEventHandler(this.OnRdpClientLogonError);
					this.RdpClient6.OnWarning += new AxMSTSCLib.IMsTscAxEvents_OnWarningEventHandler(this.OnRdpClientWarning);
					this.RdpClient6.OnConnecting += new System.EventHandler(this.OnRdpClientConnecting);
					this.RdpClient6.OnConnected += new System.EventHandler(this.OnRdpClientConnected);
					this.RdpClient6.OnLoginComplete += new System.EventHandler(this.OnRdpClientLoginComplete);
					this.RdpClient6.Resize += new System.EventHandler(this.OnRdpClientResize);
					this.RdpClient6.OnDisconnected += new AxMSTSCLib.IMsTscAxEvents_OnDisconnectedEventHandler(this.OnRdpClientDisconnected);
					this.RdpClient6.OnFatalError += new AxMSTSCLib.IMsTscAxEvents_OnFatalErrorEventHandler(this.OnRdpClientFatalError);

					this.Controls.Add(this.RdpClient6);

					((System.ComponentModel.ISupportInitialize) (this.RdpClient6)).EndInit();
				
					this.isRDPClient6Supported = true;
				}
				else if (this.RDPVersion >= (new Version(6,0,6000,16386)))
				{
					this.rdpClient5 = new AxMsRdpClient5();

					((System.ComponentModel.ISupportInitialize) (this.RdpClient5)).BeginInit();

					this.RdpClient5.Dock = System.Windows.Forms.DockStyle.Fill;
					this.RdpClient5.Enabled = true;
					this.RdpClient5.Location = new System.Drawing.Point(0,25);
					this.RdpClient5.Name = "rdpClient";
					this.RdpClient5.OcxState = ((System.Windows.Forms.AxHost.State) (resources.GetObject("rdpClient.OcxState")));
					this.RdpClient5.Size = new System.Drawing.Size(800,575);
					this.RdpClient5.TabIndex = 1;
					this.RdpClient5.OnConfirmClose += new AxMSTSCLib.IMsTscAxEvents_OnConfirmCloseEventHandler(this.OnRdpClientConfirmClose);
					this.RdpClient5.OnLogonError += new AxMSTSCLib.IMsTscAxEvents_OnLogonErrorEventHandler(this.OnRdpClientLogonError);
					this.RdpClient5.OnWarning += new AxMSTSCLib.IMsTscAxEvents_OnWarningEventHandler(this.OnRdpClientWarning);
					this.RdpClient5.OnConnecting += new System.EventHandler(this.OnRdpClientConnecting);
					this.RdpClient5.OnConnected += new System.EventHandler(this.OnRdpClientConnected);
					this.RdpClient5.OnLoginComplete += new System.EventHandler(this.OnRdpClientLoginComplete);
					this.RdpClient5.Resize += new System.EventHandler(this.OnRdpClientResize);
					this.RdpClient5.OnDisconnected += new AxMSTSCLib.IMsTscAxEvents_OnDisconnectedEventHandler(this.OnRdpClientDisconnected);
					this.RdpClient5.OnFatalError += new AxMSTSCLib.IMsTscAxEvents_OnFatalErrorEventHandler(this.OnRdpClientFatalError);

					this.Controls.Add(this.RdpClient5);

					((System.ComponentModel.ISupportInitialize) (this.RdpClient5)).EndInit();
				}
				else 
					throw new Exception("RDP Version " + this.rdpVersion.ToString() + " is not supported.");
			}
			else 
				throw new DllNotFoundException("Required RDP DLL is not found.");
		}
	#endregion

	#region Methods
		private Version GetRDPVersion()
		{
			String osInstallationPath = Environment.GetFolderPath(Environment.SpecialFolder.System).Trim();
			String rdpDLLFilePath = osInstallationPath.EndsWith("\\") ? osInstallationPath + "mstscax.dll" : osInstallationPath + "\\" + "mstscax.dll";

			if (File.Exists(rdpDLLFilePath))
			{
				FileVersionInfo rdpDLLFileVersion = FileVersionInfo.GetVersionInfo(rdpDLLFilePath);
				if (rdpDLLFileVersion != null)
					return new Version(rdpDLLFileVersion.FileMajorPart,rdpDLLFileVersion.FileMinorPart,rdpDLLFileVersion.FileBuildPart,rdpDLLFileVersion.FilePrivatePart);
			}

			return null;
		}
		public void Connect()
		{
			if (this.IsRDPClient6Supported)
				this.RdpClient6.Connect();
			else
				this.RdpClient5.Connect();
		}
		public void Disconnect()
		{
			if (this.IsRDPClient6Supported)
				this.RdpClient6.Disconnect();
			else
				this.RdpClient5.Disconnect();
		}
	#endregion

	#region Event Handlers
		private bool OnRdpClientConfirmClose(object sender,IMsTscAxEvents_OnConfirmCloseEvent iMsTscAxEvents_OnConfirmCloseEvent)
		{
			if (this.OnConfirmClose != null)
				return this.OnConfirmClose(sender,iMsTscAxEvents_OnConfirmCloseEvent);

			return default(bool);
		}
		private void OnRdpClientConnected(object sender,EventArgs eventArgs)
		{
			if (this.OnConnected != null)
				this.OnConnected(sender,eventArgs);
		}
		private void OnRdpClientConnecting(object sender,EventArgs eventArgs)
		{
			if (this.OnConnecting != null)
				this.OnConnecting(sender,eventArgs);
		}
		private void OnRdpClientDisconnected(object sender,IMsTscAxEvents_OnDisconnectedEvent iMsTscAxEvents_OnDisconnectedEvent)
		{
			if (this.OnDisconnected != null)
				this.OnDisconnected(sender,iMsTscAxEvents_OnDisconnectedEvent);
		}
		private void OnRdpClientFatalError(object sender,IMsTscAxEvents_OnFatalErrorEvent iMsTscAxEvents_OnFatalErrorEvent)
		{
			if (this.OnFatalError != null)
				this.OnFatalError(sender,iMsTscAxEvents_OnFatalErrorEvent);
		}
		private void OnRdpClientLoginComplete(object sender,EventArgs eventArgs)
		{
			if (this.OnLoginComplete != null)
				this.OnLoginComplete(sender,eventArgs);
		}
		private void OnRdpClientLogonError(object sender,IMsTscAxEvents_OnLogonErrorEvent iMsTscAxEvents_OnLogonErrorEvent)
		{
			if (this.OnLogonError != null)
				this.OnLogonError(sender,iMsTscAxEvents_OnLogonErrorEvent);
		}
		private void OnRdpClientWarning(object sender,IMsTscAxEvents_OnWarningEvent iMsTscAxEvents_OnWarningEvent)
		{
			if (this.OnWarning != null)
				this.OnWarning(sender,iMsTscAxEvents_OnWarningEvent);
		}
		private void OnRdpClientResize(object sender,EventArgs eventArgs)
		{
			if (this.OnRDPResize != null)
				this.OnRDPResize(sender,eventArgs);
		}
	#endregion
	}
}
